/*
 * AssertionConsumerService
 * 
 * Version information
 * 
 * Feb 25, 2006
 * 
 * Copyright (c) AmSoft Systems, 2006
 */
package net.amsoft.iservice.isso.webapp.struts.action;

import java.util.HashMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.amsoft.iservice.isso.client.ISSOClient;
import net.amsoft.iservice.isso.client.SAMLDataObject;
import net.amsoft.iservice.isso.webapp.dataObject.LoginData;
import net.amsoft.iservice.isso.webapp.dataObject.SPData;
import net.amsoft.iservice.isso.util.ISSOConstants;
import net.amsoft.iservice.util.ResolverClient;

import org.apache.log4j.Logger;
import org.apache.soap.Envelope;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.util.MessageResources;

/**
 * @author rahul
 * 
 */
public class AssertionConsumerService extends BaseAction {
	private static Logger oLogger = Logger
            .getLogger(AssertionConsumerService.class);

    public ActionForward process(ActionMapping oMapping,
            ActionForm oActionForm, HttpServletRequest oRequest,
            HttpServletResponse oResponse) throws Exception {
        oLogger.info("process : entry");
        ActionMessages oActionMsgs = new ActionErrors();
        LoginData oLoginData = (LoginData) oRequest.getSession(false)
                .getAttribute(ISSOConstants.SESSION_LOGIN_OBJ);
        try {
            String sSAMLArtifactDoc = oRequest
                    .getParameter(ISSOClient.PARAM_SAML_ART);
            String sRelayState = oRequest
                    .getParameter(ISSOClient.PARAM_RELAY_STATE);
            SAMLDataObject oReceivedSAMLData = ISSOClient
                    .getValuesFromSAMLArtifact(sSAMLArtifactDoc);

            HashMap ohSPData = (HashMap) oRequest.getSession(false)
                    .getAttribute(ISSOConstants.SESSION_LOGIN_HASH_OBJ);

            String sSpXri = ISSOConstants.getSPXri(oRequest.getServerName());
            SPData oSPData = (SPData) ohSPData.get(sSpXri);
            if (oSPData == null) {
                oActionMsgs.add(ActionMessages.GLOBAL_MESSAGE,
                        new ActionMessage(ISSOConstants.ERR_INVALID_REQUEST));
                saveErrors(oRequest, oActionMsgs);
                oLogger.warn("Message : Service could not be identified");
                return oMapping.findForward(ISSOConstants.INAME_FWD);
            } else if (oSPData.getSAMLData() == null) {
                oSPData.setSAMLData(new SAMLDataObject());
            }

            if (!sRelayState.equals(oSPData.getRelayState())
                    || !oSPData.getProviderIDHash().equals(
                            oReceivedSAMLData.getProviderIDHash())) {
                oActionMsgs.add(ActionMessages.GLOBAL_MESSAGE,
                        new ActionMessage(ISSOConstants.ERR_INVALID_REQUEST));
                saveErrors(oRequest, oActionMsgs);
                oLogger.debug("process : received RS=" + sRelayState
                        + ", expected RS=" + oSPData.getRelayState()
                        + "\nreceived PIDHash="
                        + oReceivedSAMLData.getProviderIDHash()
                        + ", expected PIDHash=" + oSPData.getProviderIDHash());
                return oMapping.findForward(ISSOConstants.MESSAGE_FWD);
            }

            oSPData.getSAMLData().setProviderIDHash(
                    oReceivedSAMLData.getProviderIDHash());
            oSPData.getSAMLData().setArtifact(oReceivedSAMLData.getArtifact());
            String sArtifactConsumerService = ResolverClient.getMetaDataIDP(
                    oLoginData.getIDPMetaDataEP())
                    .getArtifactResolutionServiceURL();
            String sArtifactResolveXML = ISSOClient
                    .createSAMLArtifactResolveRequest(oReceivedSAMLData
                            .getArtifact());

            Envelope oEnvelope = ISSOClient
                    .createSOAPEnvelope(sArtifactResolveXML);

            // TODO TO BE REMOVED
            MessageResources resources = getResources(oRequest);
            String cert_path = resources.getMessage("cert.path");
            String keystore_pwd = resources.getMessage("cert.pwd");
            boolean isSecure = Boolean.parseBoolean(resources
                    .getMessage("secure"));

            Envelope oReceivedEnvelope = null;
            if (isSecure) {
                oReceivedEnvelope = ISSOClient.sendAndReceiveSOAPEnvelope(
                        oEnvelope, sArtifactConsumerService);
            } else {
                oReceivedEnvelope = ISSOClient.sendAndReceiveSOAPEnvelope(
                        oEnvelope, sArtifactConsumerService, cert_path,
                        keystore_pwd);
            }
            String sArtifactResponseXML = ISSOClient
                    .getArtifactResponseFromSOAPEnvelpe(oReceivedEnvelope);
            SAMLDataObject oSAMLAuthResponseData = ISSOClient
                    .getAuthnResponseValuesFromArtifactResponse(sArtifactResponseXML);

            if (!oSPData.getGlobalInumber().equals(
                    oSAMLAuthResponseData.getSubjectNameIDNameQualifier())
                    || !oSAMLAuthResponseData.getSAMLStatus().equals(
                            ISSOClient.SAML_STATUS_SUCCESS)) {
                oActionMsgs.add(ActionMessages.GLOBAL_MESSAGE,
                        new ActionMessage(ISSOConstants.ERR_EXCEEDED_ATTEMPTS));
                saveErrors(oRequest, oActionMsgs);
                oLogger.debug("process : received GIN="
                        + oSAMLAuthResponseData.getSubjectNameIDNameQualifier()
                        + ", expected=" + oSPData.getGlobalInumber()
                        + "\nReceived SAML_STATUS="
                        + oSAMLAuthResponseData.getSAMLStatus());
                return oMapping.findForward(ISSOConstants.SUCCESS_FWD);
            }
            oLoginData
                    .setSessionCookie(oSAMLAuthResponseData.getSessionIndex());
            oLoginData.setLoginStatus(true);
            oLogger.info("process : successfull login");
            oActionMsgs.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
                    ISSOConstants.MSG_LOGIN_SUCCESS));
            saveErrors(oRequest.getSession(false), oActionMsgs);
        } catch (Exception e) {
            oLogger.error("process : Exception : " + e.getMessage());
        }
        return oMapping.findForward(ISSOConstants.SUCCESS_FWD);
    }
}